// eslint-disable-next-line no-unused-expressions
;!(() => {
  const baseUrl = ['http://192.168.1.200:8080', 'http://api.yaju.chenliang0829.cn']
  const arr = ['/orangeweb/webservice/rest']
  const list = {
    EditUser: { method: 'PUT', url: baseUrl[0] + arr[0] + '/user' },
    GetRoles: { method: 'GET', url: baseUrl[0] + arr[0] + '/roles' },
    FindStoryBycity: { method: 'Get', url: baseUrl[1] + '/story/findByCity' }
  }
  window.ajax = function (name, data = null, params, paths = [], headers = { contentType: 'application/json' }) {
    return new Promise(function (resolve, reject) {
      const http = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP')
      http.onreadystatechange = function () {
        if (!http || http.readyState !== 4) {
          // eslint-disable-next-line no-useless-return
          return
        }
        if (http.status === 0 && !(http.responseURL && http.responseURL.indexOf('file:') === 0)) {
          // eslint-disable-next-line no-useless-return
          return
        }
        /**
         * 判断返回的数据是否是 JSON 格式的字符串
         *  是: 先使用 JSON.parse 转换
         *  不是: 就直接返回传字符串
        */
        // 准备返回数据
        const response = {
          data: JSON.parse(http.response),
          status: http.status,
          statusText: http.statusText,
          headers: parseHeaders(http.getAllResponseHeaders()),
          request: http
        }
        if (http.status >= 200 & http.status <= 300 || http.status === 304) {
          resolve(response)
        } else {
          reject(new Error('Request failed with status code ' + http.status))
        }
      }
      // 根据请求名称解构赋值出 method 和 url
      const { method, url } = list[name]
      /**************************************************
       * 处理 data 数据
       *  原理: 判断 ContentType 是否为 `text/plain` 或 `text/xml`
      ***************************************************/
      if (headers.contentType && (headers.contentType !== 'text/plain' || headers.contentType !== 'text/xml')) {
        data = JSON.stringify(data)
      }
      /********************************************
       * 处理 paths 参数
       *  原理: 将 paths 参数直接以 /参数 拼接到url上,如: http://127.0.0.1:8080/user/itchenliang
       *    1. 首先判断 paths 是否以数组形式传递的 paths.constructor === Array
       *    2. 然后使用 paths.map 遍历 paths ,并和 url 进行拼接
       *        得到拼接后的结果: http://127.0.0.1:8080/user/itchenliang
       *******************************************/
      let finalUrl = url
      if (paths.constructor !== Array) {
        reject(new Error('Paths parameter error'))
      }
      paths.map(item => {
        if (item) {
          finalUrl += '/' + item
        } else {
          reject(new Error('Paths parameter error'))
        }
      })
      /********************************************
       * 处理 params 数据
       *  原理:
       *    1. 首先判断 params 是否是一个对象(根据 params 的构造函数是否为 Object 判断)
       *        不是: 返回提示信息
       *    2. 使用 for ... in 遍历 params, 并将 键值以 `key=value` 的字符串形式保存到 queryParam 中
       *    3. 拼接出最终的 url
       *        判断 url 是否有query参数( url.indexOf('?') === -1)
       *        然后使用`queryParam.join('&')`将query参数转成 `key=value&key1=value1`
       *        finalUrl += (url.indexOf('?') === -1 ? '?' : '&') + queryParam.join('&')
       *******************************************/
      params = params || {}
      if (params.constructor !== Object) {
        return reject(new Error('Params parameter error'))
      }
      const queryParam = []
      for (const key in params) {
        queryParam.push(key + '=' + params[key])
      }
      // 避免没有 query 参数时也会加上一个 ? 或 &
      if (queryParam.length >= 1) {
        finalUrl += (url.indexOf('?') === -1 ? '?' : '&')
      }
      finalUrl += queryParam.join('&')
      // 初始化一个请求
      http.open(method, finalUrl, true)
      /**
       * 动态设置 headers: 根据 http.setRequestHeader(key, val) 方法设置headers
       *  循环遍历 headers 将 (key, val) 使用 http.setRequestHeader(key, val)设置
       *    注意: 需要捕获异常,因为在设置 headers,有些 http请求头是不允许被设置的
       *      如: Accept-Charset Origin等
      */
      if (headers) {
        try {
          for (const key in headers) {
            http.setRequestHeader(key, headers[key])
          }
        } catch {
          reject(new Error('Headers parameter error'))
        }
      }
      // 设置超时时间
      // http.timeout = 1000
      // http.ontimeout = function (event) {
      //   console.log('超时啦')
      //   reject(new Error('超时啦'))
      // }
      if (method === 'GET' || method === 'PUT') {
        http.send(data)
      } else {
        http.send(null)
      }
    })
  }
  // eslint-disable-next-line no-unused-vars
  function parseHeaders (headers) {
    const parsed = {}
    var ignoreDuplicateOf = [
      'age', 'authorization', 'content-length', 'content-type', 'etag',
      'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
      'last-modified', 'location', 'max-forwards', 'proxy-authorization',
      'referer', 'retry-after', 'user-agent'
    ]
    headers.split('\n').forEach(item => {
      // 首先截取出我们 key -- value
      const index = item.indexOf(':')
      const key = item.substr(0, index).trim().toLowerCase()
      const value = item.substr(index + 1).trim()
      if (key) {
        // 忽略其重复项的 header
        if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
          return
        }
        if (key === 'set-cookie') {
          parsed[key] = (parsed[key] ? parsed[key] : []).concat([value])
        } else {
          // 判断 key 是否重复
          parsed[key] = parsed[key] ? parsed[key] + ', ' + value : value
        }
      }
    })
    return parsed
  }
}).call()
